/**
 * @file list_node.c
 * @author Linquan  
 * @brief 
 * @version 1.0
 * @date 2024-06-18
 * 
 * @copyright Copyright (c) 2024
 * 
 */


#include "list_node.h"
#include <stdio.h>


/**
 * @brief 初始化一个链表表头，手动给予 存储空间
 * 
 * @param lists      初始化的链表表头
 * @param buf        给定空间首地址
 * @param buflen     空间长度
 * @param node_bytes 链表元素的大小
 */
 void list_init_with_buff(list_head_node *lists, void *buf, int buflen, uint16_t node_bytes ) 
{
    INIT_LIST_HEAD(&lists->list);
    nodebuf_init(&lists->listbuf, buf, buflen, node_bytes);
}



/**
 * @brief Get the list num object
 * 
 * @param lists    
 * @return uint16_t : the number of list nodes 
 */
uint16_t get_list_num(list_head_node *lists)
{	
	uint16_t count = 0;
    struct list_head *list_ptr, *safe_ptr;
    list_for_each_safe(list_ptr, safe_ptr, &lists->list) 
	{
        if(count != 0XFFFF)
        {
             count++; 
        }
             
    }
	return count;
}


/***************91A 气灭分区********************/

/**
 * @brief 释放链表所有节点
 * 
 * @param lists 
 * @return uint8_t 
 */
uint8_t LIST_FREE(REPORT_DATA_91A)(list_head_node *lists)
{
    struct list_head *list_ptr, *safe_ptr;
    list_for_each_safe(list_ptr, safe_ptr, &lists->list) 
	{
       LIST_NODE_TYPE(REPORT_DATA_91A) *newlist  = list_entry(list_ptr,LIST_NODE_TYPE(REPORT_DATA_91A),list);

        list_del(list_ptr);
        nodebuf_free(&lists->listbuf, newlist);    
    }
    return 1;
}




/**
 * @brief 向指定链表插入节点
 * 
 * @param lists  指定链表
 * @param listEvent  节点
 */
 void LIST_WRITE(REPORT_DATA_91A)(         \
                    list_head_node *lists,  \
                    insert_order_t local,   \
                    report_data_t evt)
{
    LIST_NODE_TYPE(REPORT_DATA_91A)* newlistEvent = (LIST_NODE_TYPE(REPORT_DATA_91A)*)nodebuf_malloc(&lists->listbuf,0);
    if(newlistEvent != NULL)
    {
        newlistEvent->data = evt;
        if(local == HEAD_ADD) 
        {
            list_add(&newlistEvent->list, &lists->list);
        }
        
        else if(local == TAIL_ADD) 
        {
            list_add_tail(&newlistEvent->list, &lists->list);
        }
    }
    else
    {
        printf("list write fail \n");
    }
}

/**
 * @brief 读取链表指定节点内容
 * 
 * @param lists 指定的链表
 * @param order 正序、逆序读取
 * @param num 请求读取节点上第num个节点的数据
 * @param evt 存放数据的地址
 * @return uint8_t : read fail = 1 ,read suecess = 0
 */
 uint8_t LIST_READ(REPORT_DATA_91A)(\
                    list_head_node *lists,  \
                    read_order_t order,     \
                    uint16_t num,           \
                    report_data_t *evt) 
{  		
	uint16_t count = 0;
    struct list_head *list_ptr, *safe_ptr;
	
    uint8_t emp = list_empty(&lists->list);         
	
    if(emp)
	{
        return emp;
    }
    	
    if (order == POSI_READ) 
    {
        list_for_each_safe(list_ptr, safe_ptr, &lists->list) 
        {
            LIST_NODE_TYPE(REPORT_DATA_91A) *newlist = list_entry(list_ptr,LIST_NODE_TYPE(REPORT_DATA_91A),list);
            count++;
            if(count == num)
            {
                *evt =  newlist->data; // ！！！传入指针读取，传入的指针需要做解引用 ！！！
                return 0;
            }
        }
    }
    else if(order == REVER_READ)  
    {
        list_for_each_prev(list_ptr, &lists->list) 
        {
            LIST_NODE_TYPE(REPORT_DATA_91A) *newlist = list_entry(list_ptr,LIST_NODE_TYPE(REPORT_DATA_91A),list);
            count++;
            if(count == num)
            {
                *evt =  newlist->data;
                return 0;
            }
        }
    }	
	
    return 1;
    
}


/**
 * @brief 根据正序还是反序 删除指定数量的节点
 * 
 */
 uint8_t LIST_DELETE_SOME(REPORT_DATA_91A)(\
                        list_head_node *lists,  \
                        read_order_t order,     \
                        uint16_t delete_num) 
{  		
	uint16_t count = 0;
    struct list_head *list_ptr, *safe_ptr;
	
    uint8_t emp = list_empty(&lists->list);         
	
    if(emp)
	{
        return emp;
    }
    	
    if (order == POSI_READ) 
    {
        list_for_each_safe(list_ptr, safe_ptr, &lists->list) 
        {
            LIST_NODE_TYPE(REPORT_DATA_91A) *newlist = list_entry(list_ptr,LIST_NODE_TYPE(REPORT_DATA_91A),list);
            
            list_del(list_ptr);
            nodebuf_free(&lists->listbuf, newlist);

            count++;

            if(count == delete_num)
            {  
                return 0;
            }
        }
    }
    else if(order == REVER_READ)  
    {
        list_for_each_prev(list_ptr, &lists->list) 
        {
            LIST_NODE_TYPE(REPORT_DATA_91A) *newlist = list_entry(list_ptr,LIST_NODE_TYPE(REPORT_DATA_91A),list);
            
            list_del(list_ptr);
            nodebuf_free(&lists->listbuf, newlist);

            count++;

            if(count == delete_num)
            {  
                return 0;
            }
        }
    }	
	
    return 1; 
}






/**
 * @brief delete node
 * 
 * @param lists     special list whitch need delete node
 * @param evt       node need deleted
 * @return uint8_t  delete fail = 1   delete sucess = 0
 */
 uint8_t LIST_DELETE(REPORT_DATA_91A)(list_head_node *lists,  report_data_t evt)
{
    struct list_head *list_ptr, *safe_ptr;
    list_for_each_safe(list_ptr, safe_ptr, &lists->list) 
	{
       LIST_NODE_TYPE(REPORT_DATA_91A) *newlist  = list_entry(list_ptr,LIST_NODE_TYPE(REPORT_DATA_91A),list);
        
        if (\
            newlist->data.dev_addr.master_index == evt.dev_addr.master_index\
            && newlist->data.dev_addr.node_index == evt.dev_addr.node_index\
            && newlist->data.dev_addr.relay_index == evt.dev_addr.relay_index\
            ) 
		{
            list_del(list_ptr);
            nodebuf_free(&lists->listbuf, newlist);
            return 0;
        }
    }
    return 1;
}



















